home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Snippets / Demo / GraySlider.p < prev    next >
Text File  |  1997-07-22  |  6KB  |  222 lines

  1. UNIT GraySlider;
  2. INTERFACE
  3.  
  4.     USES
  5.         Types, QuickDraw, Icons, OffscreenUtils;
  6.  
  7.     CONST
  8.         kSliderBorder = 8;    { Space left between indicator and border of body }
  9.  
  10.     TYPE
  11.         SliderAxis = (axHoricontal, axVertical);
  12.         SliderActionProc = PROCEDURE (minimum, maximum, value: INTEGER);
  13.         
  14.     TYPE
  15.         GraySliderInfo = RECORD
  16.             axis: SliderAxis;
  17.             bodyRect: Rect;
  18.             bodyPict: PicHandle;
  19.             indicatorIcon, selectedIndicatorIcon: CIconHandle;
  20.             minimum, maximum, value: INTEGER;
  21.             offscreen: OffscreenAreaPtr;
  22.         END;
  23.         
  24.     PROCEDURE InitializeGraySlider(axis: SliderAxis; bodyRect: Rect; bodyPictID: INTEGER; indicatorCicnID, selectedIndicatorCicnID: INTEGER; minimum, maximum, value: INTEGER; VAR info: GraySliderInfo);
  25.     PROCEDURE DrawGraySlider(info: GraySliderInfo);
  26.     PROCEDURE FreeGraySlider(info: GraySliderInfo);
  27.     
  28.     FUNCTION HitGraySlider(info: GraySliderInfo; pt: Point): BOOLEAN;
  29.     FUNCTION TrackGraySlider(VAR info: GraySliderInfo; action: SliderActionProc): BOOLEAN;
  30.  
  31. IMPLEMENTATION
  32.  
  33.     USES
  34.         Events;
  35.  
  36.     PROCEDURE InitializeGraySlider(axis: SliderAxis; bodyRect: Rect; bodyPictID: INTEGER; indicatorCicnID, selectedIndicatorCicnID: INTEGER; minimum, maximum, value: INTEGER; VAR info: GraySliderInfo);
  37.     VAR
  38.         box: Rect;
  39.         indicatorSize, bodyCenter: INTEGER;
  40.         
  41.     BEGIN
  42.         info.axis := axis;
  43.         info.bodyRect := bodyRect;
  44.         info.bodyPict := GetPicture(bodyPictID);
  45.         info.indicatorIcon := GetCIcon(indicatorCicnID);
  46.         info.selectedIndicatorIcon := GetCIcon(selectedIndicatorCicnID);
  47.         info.minimum := minimum;
  48.         info.maximum := maximum;
  49.         info.value := value;
  50.     
  51.         IF axis = axHoricontal THEN
  52.             BEGIN
  53.                 indicatorSize := info.indicatorIcon^^.iconPMap.bounds.right + 1;
  54.                 bodyCenter := bodyRect.top + (bodyRect.bottom - bodyRect.top) DIV 2;
  55.                 
  56.                 box := bodyRect;
  57.                 box.top := bodyCenter - indicatorSize DIV 2 - 1;
  58.                 box.bottom := bodyCenter + indicatorSize DIV 2 + 1;
  59.             END
  60.         ELSE
  61.             BEGIN
  62.                 indicatorSize := info.indicatorIcon^^.iconPMap.bounds.bottom + 1;
  63.                 bodyCenter := bodyRect.left + (bodyRect.right - bodyRect.left) DIV 2;
  64.                 
  65.                 box := bodyRect;
  66.                 box.left := bodyCenter - indicatorSize DIV 2 - 1;
  67.                 box.right := bodyCenter + indicatorSize DIV 2 + 1;
  68.             END;
  69.             
  70.         AllocateOffscreenArea(box, info.offscreen);
  71.         IF info.offscreen = NIL THEN
  72.             DebugStr('InitializeGraySlider: AllocateOffscreenArea');
  73.     END;
  74.     
  75.     PROCEDURE FreeGraySlider(info: GraySliderInfo);
  76.     BEGIN
  77.         FreeOffscreenArea(info.offscreen);
  78.     END;
  79.     
  80.     FUNCTION PtToValue(info: GraySliderInfo; pt: Point): INTEGER;
  81.     VAR
  82.         width, height, range: INTEGER;
  83.         
  84.     BEGIN
  85.         range := info.maximum - info.minimum;
  86.         
  87.         IF info.axis = axHoricontal THEN
  88.             BEGIN
  89.                 width := info.bodyRect.right - info.bodyRect.left - 2 * kSliderBorder;
  90.                 pt.h := pt.h - (info.bodyRect.left + kSliderBorder);
  91.                 
  92.                 IF pt.h < 0 THEN
  93.                     PtToValue := info.minimum
  94.                 ELSE IF pt.h > width THEN
  95.                     PtToValue := info.maximum
  96.                 ELSE
  97.                     PtToValue := pt.h * range DIV width + info.minimum;
  98.             END
  99.         ELSE
  100.             BEGIN
  101.                 height := info.bodyRect.bottom - info.bodyRect.top - 2 * kSliderBorder;
  102.                 pt.v := pt.v - (info.bodyRect.top + kSliderBorder);
  103.                 
  104.                 IF pt.v < 0 THEN
  105.                     PtToValue := info.minimum
  106.                 ELSE IF pt.v > height THEN
  107.                     PtToValue := info.maximum
  108.                 ELSE
  109.                     PtToValue := pt.v * range DIV height + info.minimum;
  110.             END;
  111.     END;
  112.     
  113.     FUNCTION ValueToPt(info: GraySliderInfo): Point;
  114.     VAR
  115.         value, range: INTEGER;
  116.         width, height: INTEGER;
  117.         pt: Point;
  118.         
  119.     BEGIN
  120.         value := info.value - info.minimum;
  121.         range := info.maximum - info.minimum;
  122.         
  123.         width := info.bodyRect.right - info.bodyRect.left;
  124.         height := info.bodyRect.bottom - info.bodyRect.top;
  125.                 
  126.         IF info.axis = axHoricontal THEN
  127.             BEGIN
  128.                 width := width - 2 * kSliderBorder;
  129.                 pt.v := info.bodyRect.top + height DIV 2;
  130.                 pt.h := info.bodyRect.left + kSliderBorder + value * width DIV range;
  131.             END
  132.         ELSE
  133.             BEGIN
  134.                 height := height - 2 * kSliderBorder;
  135.                 pt.h := info.bodyRect.left + width DIV 2;
  136.                 pt.v := info.bodyRect.top + kSliderBorder + value * width DIV range;
  137.             END;
  138.             
  139.         ValueToPt := pt;
  140.     END;
  141.     
  142.     PROCEDURE CenterRectAroundPoint(r1: Rect; pt: Point; VAR r2: Rect);
  143.     VAR
  144.         width, height: INTEGER;
  145.         
  146.     BEGIN
  147.         width := r1.right - r1.left;
  148.         height := r1.bottom - r1.top;
  149.         
  150.         r2.left := pt.h - width DIV 2;
  151.         r2.top := pt.v - height DIV 2;
  152.         r2.right := r2.left + width;
  153.         r2.bottom := r2.top + height;
  154.     END;
  155.     
  156.     FUNCTION CalculateIndicatorRect(info: GraySliderInfo): Rect;
  157.     VAR
  158.         r: Rect;
  159.         
  160.     BEGIN
  161.         CenterRectAroundPoint(info.indicatorIcon^^.iconPMap.bounds, ValueToPt(info), r);
  162.         CalculateIndicatorRect := r;
  163.     END;
  164.     
  165.     PROCEDURE DrawGraySlider(info: GraySliderInfo);
  166.     VAR
  167.         r: Rect;
  168.         
  169.     BEGIN
  170.         StartDrawingOffscreen(info.offscreen);
  171.         DrawPicture(info.bodyPict, info.bodyRect);
  172.         r := CalculateIndicatorRect(info);
  173.         PlotCIcon(r, info.indicatorIcon);
  174.         CopyOffscreenToScreen(info.offscreen);
  175.     END;
  176.  
  177.     FUNCTION HitGraySlider(info: GraySliderInfo; pt: Point): BOOLEAN;
  178.     VAR
  179.         box: Rect;
  180.         
  181.     BEGIN
  182.         box := CalculateIndicatorRect(info);
  183.         HitGraySlider := PtInRect(pt, box) OR PtInRect(pt, info.bodyRect);
  184.     END;
  185.     
  186.     FUNCTION TrackGraySlider(VAR info: GraySliderInfo; action: SliderActionProc): BOOLEAN;
  187.     VAR
  188.         pt: Point;
  189.         r: Rect;
  190.         value: INTEGER;
  191.         
  192.     BEGIN
  193.         r := CalculateIndicatorRect(info);
  194.         PlotCIcon(r, info.selectedIndicatorIcon);
  195.  
  196.         WHILE Button DO
  197.             BEGIN
  198.                 GetMouse(pt);
  199.                 
  200.                 value := PtToValue(info, pt);
  201.                 IF value <> info.value THEN
  202.                     BEGIN
  203.                         StartDrawingOffscreen(info.offscreen);
  204.                         EraseRect(CalculateIndicatorRect(info));
  205.                         info.value := value;
  206.                         DrawPicture(info.bodyPict, info.bodyRect);
  207.                         r := CalculateIndicatorRect(info);
  208.                         PlotCIcon(r, info.selectedIndicatorIcon);
  209.                         CopyOffscreenToScreen(info.offscreen);
  210.                         
  211.                         IF action <> NIL THEN
  212.                             action(info.minimum, info.maximum, info.value);
  213.                     END;        
  214.             END;
  215.             
  216.         r := CalculateIndicatorRect(info);
  217.         PlotCIcon(r, info.indicatorIcon);
  218.         
  219.         TrackGraySlider := TRUE;
  220.     END;
  221.     
  222. END.